﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <vector>
#include <map>
#include <list>
#include "string.h"
using namespace std;

struct Point
{
	int _x;
	int _y;
};

class Date
{
public :
	Date(int year = 1, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{
		cout << "Date(int year, int month, int day)" << endl;
	} 

	Date(const Date& d)
		: _year(d._year)
		, _month(d._month)
		, _day(d._day)
	{
		cout << "Date(const Date& d)" << endl;
	}

private:
	int _year;
	int _month;
	int _day;
};

void PushBack(const Date& d)
{

}
//int main()
//{
//	// C++98⽀持的
//	int a1[] = { 1, 2, 3, 4, 5 };
//	int a2[5] = { 0 };
//	Point p = { 1, 2 };
//
//	// C++11⽀持的
//	// 内置类型⽀持
//	int x1 = { 2 };
//	// ⾃定义类型⽀持
//	// 这⾥本质是⽤{ 2025, 1, 1}构造⼀个Date临时对象
//	// 临时对象再去拷⻉构造d1，编译器优化后合⼆为⼀变成{ 2025, 1, 1}直接构造初始化
//
//	// 运⾏⼀下，我们可以验证上⾯的理论，发现是没调⽤拷⻉构造的
//	string str = "111111";
//	Date d0 = 2020;
//	Date d1 = { 2025, 1, 1 };
//
//	// 这⾥d2引⽤的是{ 2020, 1, 1 }构造的临时对象
//	const Date& r1 = 2020;
//	// 这⾥d2引⽤的是{ 2024, 7, 25 }构造的临时对象
//	const Date& d2 = { 2024, 7, 25 };
//
//	Date d3(2025, 1, 1);
//	PushBack({2025, 1, 1});
//	PushBack(2020);
//	PushBack({2020, 12});
//
//	// 可以省略掉=
//	Point p1{ 1, 2 };
//	int x2{ 2 };
//	Date d6{ 2024, 7, 25 };
//	const Date& d7{ 2024, 7, 25 };
//
//	// 不⽀持，只有{}初始化，才能省略=
//	// Date d8 2025;
//
//	vector<Date> v;
//	v.push_back(d1);
//	v.push_back(Date(2025, 1, 1));
//	// ⽐起有名对象和匿名对象传参，这⾥{}更有性价⽐
//	v.push_back({ 2025, 1, 1 });
//
//	
//
//	
//	return 0;
//}

//int main()
//{
//	auto il = { 10, 20 , 30 };
//	cout << typeid(il).name() << endl;
//
//	cout << il.begin() << endl;
//	cout << il.end() << endl;
//	int i = 0;
//	cout << &i << endl;
//	int j = 0;
//	cout << &j << endl;
//
//	cout << sizeof(il) << endl;
//
//	vector<int> v1 = { 1, 2, 3, 4 };
//	v1 = { 10, 20 ,30 };
//
//	map<string, string> dict = { {"sort", "排序"}, {"left", "左边"} };
//
//	return 0;
//}

//int main()
//{
//	// 左值：可以取地址
//	// 以下的p、b、c、*p、s、s[0]就是常⻅的左值
//	int* p = new int(0);
//	int b = 1;
//	const int c = b;
//	*p = 10;
//	string s("111111");
//	s[0] = 'x';
//	cout << &c << endl;
//	cout << (void*)&s[0] << endl;
//
//
//
//
//	// 右值：不能取地址
//	double x = 1.1, y = 2.2;
//	// 以下⼏个10、x + y、fmin(x, y)、string("11111")都是常⻅的右值
//	10;
//	x + y;
//	fmin(x, y);
//	string("11111");
//
//	//cout << &10 << endl;
//	//cout << &(x+y) << endl;
//	//cout << &(fmin(x, y)) << endl;
//	//cout << &string("11111") << endl;
//
//	int&& rr1 = 10;
//	double&& rr2 = x + y;
//	string&& rr3 = string("11111");
//
//	const double& r2 = x + y;
//
//	int&& rr4 = move(b);
//	//int&& rr4 = (int&&)b;
//
//	return 0;
//}

//int main()
//{
//	std::string s1 = "Test";
//	// std::string&& r1 = s1; // 错误：不能绑定到左值
//
//	const std::string& r2 = s1 + s1; // OK：到 const 的左值引⽤延⻓⽣存期
//	// r2 += "Test"; // 错误：不能通过到 const 的引⽤修改
//
//	std::string&& r3 = s1 + s1; // OK：右值引⽤延⻓⽣存期
//	r3 += "Test"; // OK：能通过到⾮ const 的引⽤修改
//
//
//	std::cout << r3 << '\n';
//
//
//	return 0;
//}


class AA
{
public:
	AA(int a1, int a2)
		:_a1(a1), _a2(a2)
	{
	}

	~AA()
	{
		cout << "~AA()" << endl;
	}

private:
	int _a1 = 1;
	int _a2 = 1;
};

//int main()
//{
//	AA aa1(1, 1);
//	const AA& r1 = AA(2, 2);
//	AA&& rr1 = AA(2, 2);
//
//	cout << "-----------------------------------" << endl;
//
//	return 0;
//}

void f(int& x)
{
	std::cout << "左值引用重载 f(" << x << ")\n";
} 

void f(const int& x)
{
	std::cout << "到 const 的左值引用重载 f(" << x << ")\n";
} 

void f(int&& x)
{
	std::cout << "右值引用重载 f(" << x << ")\n";
} 

//int main()
//{
//	int i = 1;
//	const int ci = 2;
//
//	f(i); // 调⽤ f(int&)
//	f(ci); // 调⽤ f(const int&)
//	f(3); // 调⽤ f(int&&)，如果没有 f(int&&) 重载则会调⽤ f(const int&)
//	f(std::move(i)); // 调⽤ f(int&&)
//
//	// 右值引⽤变量在⽤于表达式时是左值
//	// 变量表达式都是左值属性
//	int&& x = 1;
//	f(x); // 调⽤ f(int& x)
//	f(std::move(x)); // 调⽤ f(int&& x)
//	int& y = i;
//	f(y);
//
//	return 0;
//}

class Solution1 {
public:
	// 传值返回需要拷⻉
	string addStrings(string num1, string num2) {
		string str;
		int end1 = num1.size() - 1, end2 = num2.size() - 1;

		// 进位
		int next = 0;
		while (end1 >= 0 || end2 >= 0)
		{
			int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
			int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
			int ret = val1 + val2 + next;
			next = ret / 10;
			ret = ret % 10;
			str += ('0' + ret);
		} 
		
		if(next == 1)
			str += '1';
		reverse(str.begin(), str.end());
		return str;
	}
};

class Solution2 {
public:
	// 这⾥的传值返回拷⻉代价就太⼤了
	vector<vector<int>> generate(int numRows) {
		vector<vector<int>> vv(numRows);
		for (int i = 0; i < numRows; ++i)
		{
			vv[i].resize(i + 1, 1);
		}

		for (int i = 2; i < numRows; ++i)
		{
			for (int j = 1; j < i; ++j)
			{
				vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];
			}
		}

		return vv;
	}
};


//int main()
//{
//	std::list<my_string::string> lt;
//	my_string::string s1("111111111111111111111");
//	lt.push_back(s1); // 左值
//	cout << "*************************" << endl;
//
//	lt.push_back(my_string::string("22222222222222222222222222222"));	// 右值
//	cout << "*************************" << endl;
//
//	lt.push_back("3333333333333333333333333333");
//	cout << "*************************" << endl;
//
//	lt.push_back(move(s1));
//	cout << "*************************" << endl;
//	return 0;
//}

//#include "string.h"
//int main()
//{
//	my_string::string ret;
//	cout << "******************************" << endl;
//	ret = my_string::addStrings("11111", "2222");
//	//cout << &ret << endl;
//	cout << ret.c_str() << endl;
//	cout << "******************************" << endl;
//
//
//
//	return 0;
//}


//int main()
//{
//	 
//	my_string::string s1("xxxxx");
//	cout << s1.c_str() << endl;
//
//	// 拷⻉构造
//	my_string::string s2 = s1;
//
//	// 构造+移动构造，优化后直接构造
//	my_string::string s3 = my_string::string("yyyyy");
//
//	// 移动构造
//	my_string::string s4 = move(s1);
//	cout << s1.c_str() << endl;
//	cout << "******************************" << endl;
//
//
//	return 0;
//}

//int main()
//{
//	// 1. 构造与打印
//	my_string::string s1("hello");
//	cout << "s1: " << s1.c_str() << " (size: " << s1.size() << ")" << endl;  // 输出 hello (size:5)
//
//	// 2. 拷贝构造
//	my_string::string s2 = s1;  // 调用拷贝构造
//	cout << "s2: " << s2.c_str() << endl;  // 输出 hello
//
//	// 3. 移动构造
//	my_string::string s3 = std::move(s1);  // 调用移动构造，s1资源转移给s3
//	cout << "s3: " << s3.c_str() << endl;  // 输出 hello
//
//	// 4. 追加字符
//	s3 += " world";
//	cout << "s3 after +=: " << s3.c_str() << endl;  // 输出 hello world
//
//	// 5. 范围for遍历
//	cout << "s3遍历: ";
//	for (auto ch : s3)
//	{
//		cout << ch;
//	}
//	cout << endl;  // 输出 hello world
//
//	return 0;
//}

#include "lish.h"
//int main()
//{
//	my_list::list<my_string::string> lt;
//	my_string::string s1("111111111111111111111");
//	lt.push_back(s1); // 左值
//	cout << "*************************" << endl;
//
// 	lt.push_back(my_string::string("22222222222222222222222222222"));	// 右值
//	cout << "*************************" << endl;
//
//	lt.push_back("3333333333333333333333333333");
//	cout << "*************************" << endl;
//
//	lt.push_back(move(s1));
//	cout << "*************************" << endl;
//
//	 
//	return 0;
//}

// 由于引⽤折叠限定，f1实例化以后总是⼀个左值引⽤
template<class T>
void f1(T& x)
{
}
// 由于引⽤折叠限定，f2实例化后可以是左值引⽤，也可以是右值引⽤
template<class T>
void f2(T&& x)
{
}

//int main()
//{
//	typedef int& lref;
//	typedef int&& rref;
//	int n = 0;
//
//	lref& r1 = n;  // int&
//	lref&& r2 = n; // int&
//	rref& r3 = n;  // int&
//	rref&& r4 = 1; // int&&
//
//	// f1(T&) 调用
//	f1<int>(n);         // ✅ int& 绑定左值n
//	f1<int>(0);			// ❌ 非const左值引用不能绑定右值
//
//	f1<int&>(n);        // ✅ (int&)&=int& 绑定左值n
//	f1<int&>(0);		// ❌ 非const左值引用不能绑定右值
//
//	f1<int&&>(n);       // ✅ (int&&)&=int& 绑定左值n
//	f1<int&&>(0);		// ❌ 非const左值引用不能绑定右值
//
//	// f1(const T&) 调用（const左值引用可绑定右值）
//	f1<const int&>(n);  // ✅ const int& 绑定左值n
//	f1<const int&>(0);  // ✅ const int& 可绑定右值0
//	f1<const int&&>(n); // ✅ (const int&&)&=const int& 绑定左值n
//	f1<const int&&>(0); // ✅ const int& 可绑定右值0
//
//	// f2(T&&) 调用（万能引用/显式指定T）
//	// f2<int>(n);      // ❌ int&& 不能绑定左值n
//	f2<int>(0);         // ✅ int&& 绑定右值0
//	f2<int&>(n);        // ✅ (int&)&&=int& 绑定左值n
//	f2<int&>(0);		// ❌ 非const左值引用不能绑定右值
//	f2<int&&>(n);		// ❌ int&& 不能绑定左值n
//	f2<int&&>(0);       // ✅ int&& 绑定右值0
//
//	// 万能引用的正确用法（自动推导T）
//	f2(n);              // ✅ T=int& → int&，绑定左值n
//	f2(0);              // ✅ T=int → int&&，绑定右值0
//
//	return 0;
//}


// 万能引用
//template<class T>	// T 只应推导 “原始类型” 或 “左值引用类型”
//void Function(T&& t)
//{
//	int a = 0;
//	T x = a;
//	//x++;
//	cout << &a << endl;
//	cout << &x << endl << endl;
//} 

//int main()
//{
//	// 10是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(10); // 右值
//
//	int a;
//	// a是左值，推导出T为int&，引⽤折叠，模板实例化为void Function(int& t)
//	Function(a); // 左值
//
//	// std::move(a)是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(std::move(a)); // 右值
//
//	const int b = 8;
//	// b是左值，推导出T为const int&，引⽤折叠，模板实例化为void Function(const int& t)
//	// 所以Function内部会编译报错，x不能++
//	Function(b); // const 左值
//
//    // std::move(b)右值，推导出T为const int，模板实例化为void Function(const int&& t)
//	// 所以Function内部会编译报错，x不能++
//	Function(std::move(b)); // const 右值
//
//	return 0;
//}
#include <type_traits>
//template <class _Ty>
//_Ty&& forward(remove_reference_t<_Ty>& _Arg) noexcept
//{ 
//	// forward an lvalue as either an lvalue or an rvalue
//	return static_cast<_Ty&&>(_Arg);
//} 

void Fun(int& x) { cout << "左值引用" << endl; }
void Fun(const int& x) { cout << "const 左值引用" << endl; }
void Fun(int&& x) { cout << "右值引用" << endl; }
void Fun(const int&& x) { cout << "const 右值引用" << endl; }

// 万能引用
template<class T>
void Function(T&& t)
{
	//Fun(t);	
	// C++ 中有一个关键规则：无论变量的类型是左值引用还是右值引用，变量本身都是左值。
	// 左值引用		  // Function(10)：t是int&&类型的左值，匹配Fun(int&)
	// 左值引用		  // Function(a)：t是int&类型的左值，匹配Fun(int&)
	// 左值引用		  // Function(std::move(a))：t是int&&类型的左值，匹配Fun(int&)
	// const 左值引用  // Function(b)：t是const int&类型的左值，匹配Fun(const int&)
	// const 左值引用  // Function(std::move(b))：t是const int&&类型的左值，匹配Fun(const int&)

	Fun(std::forward<T>(t));
	// 右值引用          // Function(10)：转发右值，匹配 Fun(int&&)
	// 左值引用          // Function(a)：转发左值，匹配 Fun(int&)
	// 右值引用          // Function(std::move(a))：转发右值，匹配 Fun(int&&)
	// const 左值引用    // Function(b)：转发 const 左值，匹配 Fun(const int&)
	// const 右值引用    // Function(std::move(b))：转发 const 右值，匹配 Fun(const int&&)
}
	
//int main()
//{
//	// !!!!!!!!!!!!!!!!!!!!!!! 右值引用去引用右值后会退化成左值 !!!!!!!!!!!!!!!!!!!!!!!
//	
//	// 10是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(10); // 右值
//	
//	int a;
//	// a是左值，推导出T为int&，引用折叠，模板实例化为void Function(int& t)
//	Function(a); // 左值
//	
//	// std::move(a)是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(std::move(a)); // 右值
//	
//	const int b = 8;
//	// a是左值，推导出T为const int&，引⽤折叠，模板实例化为void Function(const int& t)
//	Function(b); // const 左值
//	
//	// std::move(b)右值，推导出T为const int，模板实例化为void Function(const int&& t)
//	Function(std::move(b)); // const 右值
//	
//	
//	return 0;
//}

//int main()
//{
//
//	auto add1 = [](int x, int y)-> int {return x + y; };
//	
//	//[] ：捕获列表（此处为空，表示不捕获任何外部变量）。捕捉为空也不能省略
//	//(int x, int y)：参数列表，与普通函数的参数声明类似。参数为空可以省略
//	//->int：返回类型声明（C++11 起支持，若表达式返回类型明确，可省略，编译器会自动推导）。返回值可以省略，可以通过返回对象⾃动推导
//	//{ return x + y; }：函数体，实现两数相加并返回结果。函数	体不能省略
//
//	cout << add1(1, 2) << endl;
//
//	auto func1 = []
//		{
//			cout << "hello bit" << endl;
//			return 0;
//		};
//
//	func1();
//
//	auto swap1 = [](int& x, int& y)->int
//		{
//			int temp = x;
//			x = y;
//			y = temp;
//		}; 
//
//
//	return 0;
//}

struct Goods
{
	string _name; // 名字
	double _price; // 价格
	int _evaluate; // 评价
	// ...
	Goods(const char* str, double price, int evaluate)
		:_name(str)
		, _price(price)
		, _evaluate(evaluate)
	{
	}
};

struct ComparePriceLess
{
	bool operator()(const Goods& gl, const Goods& gr)
	{
		return gl._price < gr._price;
	}
};

struct ComparePriceGreater
{
	bool operator()(const Goods& gl, const Goods& gr)
	{
		return gl._price > gr._price;
	}
};

//int main()
//{
//	vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3
//	}, { "菠萝", 1.5, 4 } };
//
//	// 类似这样的场景，我们实现仿函数对象或者函数指针⽀持商品中
//	// 不同项的⽐较，相对还是⽐较⿇烦的，那么这⾥lambda就很好⽤了
//	sort(v.begin(), v.end(), ComparePriceLess());
//	sort(v.begin(), v.end(), ComparePriceGreater());
//
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) { return g1._price < g2._price; });
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) { return g1._price > g2._price; });
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) { return g1._evaluate < g2._evaluate; });
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) { return g1._evaluate > g2._evaluate; });
//
//	return 0;
//}

//int x = 0;
//// 捕捉列表必须为空，因为全局变量不⽤捕捉就可以⽤，没有可被捕捉的变量
////auto func1 = []() { x++; };
//
//int main()
//{
//	// 只能⽤当前lambda局部域和捕捉的对象和全局对象
//	int a = 0, b = 1, c = 2, d = 3;
//	auto func1 = [a, &b]()
//		{
//			// 值捕捉的变量不能修改，引⽤捕捉的变量可以修改
//			//a++;
//			b++;
//			int ret = a + b;
//			return ret;
//		};
//	cout << func1() << endl;
//
//
//	// 隐式值捕捉
//	// ⽤了哪些变量就捕捉哪些变量
//	auto func2 = [=]()
//		{
//			int ret = a + b + c;
//			return ret;
//		};
//	cout << func2() << endl;
//
//	// 隐式引⽤捕捉
//	// ⽤了哪些变量就捕捉哪些变量
//	auto func3 = [&]()
//	{
//		a++;
//		c++;
//		d++;
//	};
//	func3();
//	cout << a << " " << b << " " << c << " " << d << endl;
//
//	// 混合捕捉1
//	auto func4 = [&, a, b]()
//	{
//		//a++;
//		//b++;
//		c++;
//		d++;
//		return a + b + c + d;
//	};
//	func4();
//	cout << a << " " << b << " " << c << " " << d << endl;
//
//	// 混合捕捉2
//	auto func5 = [=, &a, &b]()
//		{
//			a++;
//			b++;
//			/*c++;
//			d++;*/
//			return a + b + c + d;
//		};
//	func5();
//	cout << a << " " << b << " " << c << " " << d << endl;
//
//	// 局部的静态和全局变量不能捕捉，也不需要捕捉
//	static int m = 0;
//	auto func6 = []()
//	{
//		int ret = x + m;
//		return ret;
//	};
//	cout << func6() << endl;
//
//
//	// 传值捕捉本质是⼀种拷⻉,并且被const修饰了
//	// mutable相当于去掉const属性，可以修改了
//	// 但是修改了不会影响外⾯被捕捉的值，因为是⼀种拷⻉
//	auto func7 = [=]()mutable
//		{
//			a++;
//			b++;
//			c++;
//			d++;
//			return a + b + c + d;
//		};
//	cout << func7() << endl;
//	cout << a << " " << b << " " << c << " " << d << endl;
//
//	return 0;
//}

//template<class ...Args>
//void Print(Args&&... args)
//{
//	cout << sizeof... << endl;
//}
//
//int main()
//{
//	double x = 2.2;
//	Print(); // 包⾥有0个参数
//	Print(1); // 包⾥有1个参数
//	Print(1, string("xxxxx")); // 包⾥有2个参数
//	Print(1.1, string("xxxxx"), x); // 包⾥有3个参数
//	return 0;
//}

//void ShowList()
//{
//	// 编译器时递归的终⽌条件，参数包是0个时，直接匹配这个函数
//	cout << endl;
//}
//
//template<class T, class ...Args>
//void ShowList(T x, Args... args)
//{
//	cout << x << " ";
//	// args是N个参数的参数包
//	// 调⽤ShowList，参数包的第⼀个传给x，剩下N-1传给第⼆个参数包
//	ShowList(args...);
//}
//
//// 编译时递归推导解析参数
//template <class ...Args>
//void Print(Args... args)
//{
//	ShowList(args...);
//} 
//
//int main()
//{
//	Print();
//	Print(1);
//	Print(1, string("xxxxx"));
//	Print(1, string("xxxxx"), 2.2);
//	return 0;
//}

//template <class T>
//const T& GetArg(const T& x)
//{
//	cout << x << " ";
//	return x;
//} 
//
//template <class ...Args>
//void Arguments(Args... args)
//{}
//
//template <class ...Args>
//void Print(Args... args)
//{
//	// 注意GetArg必须返回或者到的对象，这样才能组成参数包给Arguments
//	Arguments(GetArg(args)...);
//	cout << endl;
//}
//
//int main()
//{
//	Print();
//	Print(1);
//	Print(1, string("xxxxx"));
//	Print(1, string("xxxxx"), 2.2);
//	return 0;
//}


#include<list>
// emplace_back总体⽽⾔是更⾼效，推荐以后使⽤emplace系列替代insert和push系列
//int main() {
//	// 存储my_string::string的list
//	my_list::list<my_string::string> lt;
//	// 传左值，走拷贝构造
//	my_string::string s1("111111111111");
//	lt.emplace_back(s1);
//	std::cout << "*********************************" << std::endl;
//
//	// 右值，走移动构造
//	lt.emplace_back(std::move(s1));
//	std::cout << "*********************************" << std::endl;
//
//	// 直接用字符串字面量构造
//	lt.emplace_back("111111111111");
//	std::cout << "*********************************" << std::endl;
//
//	// 存储pair<my_string::string, int>的list
//	std::list<std::pair<my_string::string, int>> lt1;
//	// 构造pair + 拷贝/移动构造pair到list的节点中
//	std::pair<my_string::string, int> kv("苹果", 1);
//	lt1.emplace_back(kv);
//	std::cout << "*********************************" << std::endl;
//
//	// 移动构造pair
//	lt1.emplace_back(std::move(kv));
//	std::cout << "*********************************" << std::endl;
//
//	// 直接用参数包构造pair
//	lt1.emplace_back("苹果", 1);
//	std::cout << "*********************************" << std::endl;
//
//	// 打印lt中的元素
//	for (const auto& str : lt) {
//		std::cout << str.c_str() << " ";
//	}
//	std::cout << std::endl;
//
//	// 打印lt1中的元素
//	for (const auto& pair : lt1) {
//		std::cout << pair.first.c_str() << " " << pair.second << " ";
//	}
//	std::cout << std::endl;
//
//	return 0;
//}

//class Person
//{
//public :
//	Person(const char* name = "", int age = 0)
//		: _name(name)
//		, _age(age)
//	{}
//
//	Person(const Person& p) = default;
//	Person(Person&& p) = default;
//	Person& operator =(const Person& p) = default;
//	Person& operator =(Person&& p) = default;
//
//	~Person() {}
//
//private:
//	my_string::string _name;
//	int _age;
//};
//int main()
//{
//	Person s1;
//	Person s2 = s1;
//	Person s3 = std::move(s1);
//	Person s4;
//	s4 = std::move(s2);
//
//
//	return 0;
//}

#include<functional>
//// 普通函数（无重载）
//int f(int a, int b) { return a + b; }
//
//// 函数对象（无重载）
//struct Functor {
//public:
//	int operator() (int a, int b) { return a + b; }
//};
//
//// 类（成员函数无重载）
//class Plus {
//public:
//	Plus(int n = 10) : _n(n) {}
//
//	// 静态成员函数（无重载）
//	static int plusi(int a, int b) { return a + b; }
//
//	// 普通成员函数（无重载）
//	double plusd(double a, double b) { return (a + b) * _n; }
//
//private:
//	int _n;
//};
//
//int main()
//{
//	// 1. 包装普通函数：显式转换为函数指针类型
//	typedef int(*IntFunc)(int, int); // 定义函数指针类型（接收两个int，返回int）
//	function<int(int, int)> f1 = (IntFunc)f; // 强制转换，消除歧义
//
//	// 2. 包装函数对象（无重载，直接赋值）
//	function<int(int, int)> f2 = Functor();
//	// 3. 包装lambda表达式（无重载，直接赋值）
//	function<int(int, int)> f3 = [](int a, int b) { return a + b; };
//
//	cout << f1(1, 1) << endl;
//	cout << f2(1, 1) << endl;
//	cout << f3(1, 1) << endl;
//
//	// 4. 包装静态成员函数（无重载，直接赋值）
//	function<int(int, int)> f4 = &Plus::plusi;
//	cout << f4(1, 1) << endl; // 输出 2
//
//	// 5. 包装普通成员函数（处理隐含this）
//	function<double(Plus*, double, double)> f5 = &Plus::plusd;
//	Plus pd;
//	cout << f5(&pd, 1.1, 1.1) << endl; // 输出 22.0（(1.1+1.1)*10）
//
//	function<double(Plus, double, double)> f6 = &Plus::plusd;
//	cout << f6(pd, 1.1, 1.1) << endl; // 输出 22.0
//	cout << f6(pd, 1.1, 1.1) << endl; // 输出 22.0
//
//	function<double(Plus&&, double, double)> f7 = &Plus::plusd;
//	cout << f7(move(pd), 1.1, 1.1) << endl; // 输出 22.0
//	cout << f7(Plus(), 1.1, 1.1) << endl;   // 输出 22.0
//
//
//	return 0;
//}

using placeholders::_1;
using placeholders::_2;
using placeholders::_3;

int Sub(int a, int b)
{
	return (a - b) * 10;
} 

int SubX(int a, int b, int c)
{
	return (a - b - c) * 10;
} 

class Plus
{	
public :
	static int plusi(int a, int b)
	{
		return a + b;
	} 

	double plusd(double a, double b)
	{
		return a + b;
	}
};
int main()
{
	auto sub1 = bind(Sub, _1, _2);
	cout << sub1(10, 5) << endl;

	// bind 本质返回的⼀个仿函数对象
	// 调整参数顺序（不常⽤）
	// _1代表第⼀个实参
	// _2代表第⼆个实参
	// ...
	auto sub2 = bind(Sub, _2, _1);
	cout << sub2(10, 5) << endl;
	 
	// 调整参数个数 （常⽤）
	auto sub3 = bind(Sub, 100, _1);
	cout << sub3(5) << endl;
	auto sub4 = bind(Sub, _1, 100);
	cout << sub4(5) << endl;

	// 分别绑死第123个参数
	auto sub5 = bind(SubX, 100, _1, _2);
	cout << sub5(5, 1) << endl;
	auto sub6 = bind(SubX, _1, 100, _2);
	cout << sub6(5, 1) << endl;
	auto sub7 = bind(SubX, _1, _2, 100);
	cout << sub7(5, 1) << endl;

	// 成员函数对象进⾏绑死，就不需要每次都传递了
	function<double(Plus&&, double, double)> f6 = &Plus::plusd;
	Plus pd;
	cout << f6(move(pd), 1.1, 1.1) << endl;
	cout << f6(Plus(), 1.1, 1.1) << endl;

	// bind⼀般⽤于，绑死⼀些固定参数
	function<double(double, double)> f7 = bind(&Plus::plusd, Plus(), _1, _2);
	cout << f7(1.1, 1.1) << endl;

	// 计算复利的lambda
	auto func1 = [](double rate, double money, int year)->double
		{
			double ret = money;
			for (int i = 0; i < year; i++)
			{
				ret += ret * rate;
			}

			return ret - money;
		};

	// 绑死⼀些参数，实现出⽀持不同年华利率，不同⾦额和不同年份计算出复利的结算利息
	function<double(double)> func3_1_5 = bind(func1, 0.015, _1, 3);
	function<double(double)> func5_1_5 = bind(func1, 0.015, _1, 5);
	function<double(double)> func10_2_5 = bind(func1, 0.025, _1, 10);
	function<double(double)> func20_3_5 = bind(func1, 0.035, _1, 30);
	cout << func3_1_5(1000000) << endl;
	cout << func5_1_5(1000000) << endl;
	cout << func10_2_5(1000000) << endl;
	cout << func20_3_5(1000000) << endl;

	return 0;
}
